package com.atguigu.tingshu.album.service.impl;

import com.alibaba.fastjson.JSONObject;
import com.alibaba.nacos.shaded.com.google.gson.JsonObject;
import com.atguigu.tingshu.album.mapper.*;
import com.atguigu.tingshu.album.service.BaseCategoryService;
import com.atguigu.tingshu.common.cache.TsCache;
import com.atguigu.tingshu.model.album.*;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

@Service
@SuppressWarnings({"all"})
public class BaseCategoryServiceImpl extends ServiceImpl<BaseCategory1Mapper, BaseCategory1> implements BaseCategoryService {

    @Autowired
    private BaseCategory1Mapper baseCategory1Mapper;
    @Autowired
    private BaseCategory2Mapper baseCategory2Mapper;
    @Autowired
    private BaseCategory3Mapper baseCategory3Mapper;
    @Autowired
    private BaseCategoryViewMapper baseCategoryViewMapper;
    @Autowired
    private BaseAttributeMapper baseAttributeMapper;

    /**
     * 查询分类数据
     *
     * @return
     */
    @Override
    public List<JSONObject> getBaseCategoryList() {
        //创建返回值 list
        ArrayList<JSONObject> category1List = new ArrayList<>();
        //通过 查询 预先定义的视图 查询所有分类信息
        List<BaseCategoryView> baseCategoryViews = baseCategoryViewMapper.selectList(null);
        //1.1 先把一级分类数据查询出来，分组 封装map集合，以方便根据父id查询
        Map<Long, List<BaseCategoryView>> category1Collect = baseCategoryViews.stream().collect(Collectors.groupingBy(BaseCategoryView::getCategory1Id));
        //通过 iterator 遍历
        Iterator<Map.Entry<Long, List<BaseCategoryView>>> category1iterator = category1Collect.entrySet().iterator();
        //判断是否有下一个
        while (category1iterator.hasNext()) {
            //获取到一级分类数据
            Map.Entry<Long, List<BaseCategoryView>> category = category1iterator.next();
            //获取到一级分类id
            Long category1Id = category.getKey();
            //获取到一级分类数据
            List<BaseCategoryView> category1Value = category.getValue();
            //封装一级分类数据
            JSONObject category1 = new JSONObject();
            category1.put("categoryId", category1Id);
            category1.put("categoryName", category1Value.get(0).getCategory1Name());
            //2.定义二级分类数据 封装list
            ArrayList<JSONObject> category2List = new ArrayList<>();
            //把二级分类数据查询出来，分组
            Map<Long, List<BaseCategoryView>> category2Collect = category1Value.stream().collect(Collectors.groupingBy(BaseCategoryView::getCategory2Id));
            //遍历
            Iterator<Map.Entry<Long, List<BaseCategoryView>>> category2iterator = category2Collect.entrySet().iterator();
            //判断是否有下一个
            while (category2iterator.hasNext()) {
                //获取到二级分类数据
                Map.Entry<Long, List<BaseCategoryView>> category2 = category2iterator.next();
                //获取到二级分类id
                Long category2Id = category2.getKey();
                //获取到二级分类数据
                List<BaseCategoryView> category2Value = category2.getValue();
                //封装二级分类数据
                JSONObject category2Json = new JSONObject();
                category2Json.put("categoryId", category2Id);
                category2Json.put("categoryName", category2Value.get(0).getCategory2Name());
                //获取到三级分类数据
                List<JSONObject> category3List = category2Value.stream().map(BaseCategoryView -> {
                    //定义三级分类数据 json
                    JSONObject category3Json = new JSONObject();
                    //封装三级分类数据
                    category3Json.put("categoryId", BaseCategoryView.getCategory3Id());
                    category3Json.put("categoryName", BaseCategoryView.getCategory3Name());
                    return category3Json;
                }).collect(Collectors.toList());
                //封装三级分类数据 到二级分类categoryChild
                category2Json.put("categoryChild", category3List);
                //把二级分类数据 放入 二级list
                category2List.add(category2Json);
            }
            //封装二级分类list 到一级分类categoryChild
            category1.put("categoryChild", category2List);
            //把一级分类数据放入一级list
            category1List.add(category1);
        }
        return category1List;
    }

    /**
     * 根据分类id查询分类数据
     *
     * @param id
     * @return
     */

    @Override
    public List<BaseAttribute> findAttribute(Long id) {
        List<BaseAttribute> findAttribute = baseAttributeMapper.findAttribute(id);
        return findAttribute;
    }

    /**
     * 根据分类id查询分类数据
     *
     * @param category3Id
     * @return
     */
    @TsCache(prefix = "category:")
    @Override
    public BaseCategoryView getCategoryView(Long category3Id) {

        BaseCategoryView baseCategoryView = baseCategoryViewMapper.selectById(category3Id);

        return baseCategoryView;
    }

    /**
     * 根据分类id查询分类数据
     *
     * @param id
     * @return
     */
    @Override
    public JSONObject getBaseCategory(Long id) {
        //根据一级分类id 查询一级分类数据库 获取一级分类名
        BaseCategory1 baseCategory1 = baseCategory1Mapper.selectById(id);
        //赋值 一级分类id 和一级分类名
        JSONObject jsonObject = new JSONObject();
        jsonObject.put("categoryId", baseCategory1.getId());
        jsonObject.put("categoryName", baseCategory1.getName());
        //通过一级分类id 查询视图 数据表 获取全部分类信息
        List<BaseCategoryView> baseCategoryViews = baseCategoryViewMapper.selectList(new LambdaQueryWrapper<BaseCategoryView>().eq(BaseCategoryView::getCategory1Id, id));
        //将全部分类信息 按二级分类id分组
        Map<Long, List<BaseCategoryView>> category2IdMap = baseCategoryViews.stream().collect(Collectors.groupingBy(BaseCategoryView::getCategory2Id));
        //创建一级分类 categoryChild 列表
        ArrayList<JSONObject> categoryChild = new ArrayList<>();
        //循环遍历 按二级分类id分组 的 map 通过迭代器方式
        Iterator<Map.Entry<Long, List<BaseCategoryView>>> entryIterator = category2IdMap.entrySet().iterator();

        //判断迭代器 是否有下一个
        while (entryIterator.hasNext()) {
            //获取迭代器 下一个数据
            Map.Entry<Long, List<BaseCategoryView>> entryMap = entryIterator.next();
            //迭代器map 的key为分组条件 即二级分类id
            Long category2Id = entryMap.getKey();
            //迭代器的value 为视图数据表 一级分类id 的一条数据
            List<BaseCategoryView> category3List = entryMap.getValue();
            //赋值 二级分类id 和二级分类名  jsonObject2必须赋值一个创建一个 否则赋值时 赋值的是上一次保存的 每次循环为临时变量
            JSONObject jsonObject2 = new JSONObject();
            jsonObject2.put("categoryId", category2Id);
            jsonObject2.put("categoryName", category3List.get(0).getCategory2Name());
            //遍历三级分类 无需分组，因为三级为最终一级 属性id和属性值均不相同 使用stream流依次遍历赋值即可 jsonObject3必须赋值一个创建一个形同名的 return后销毁 否则赋值时 赋值的是上一次保存的
            List<JSONObject> category3Child = category3List.stream().map(category3 -> {
                JSONObject jsonObject3 = new JSONObject();
                jsonObject3.put("categoryId", category3.getCategory3Id());
                jsonObject3.put("categoryName", category3.getCategory3Name());
                return jsonObject3;
            }).collect(Collectors.toList());

            //将 category3Child list 整体 赋值到 jsonObject 2中
            jsonObject2.put("categoryChild",category3Child);
            //每次循环 在一级categoryChild 中 添加一个 二级分类 对象
            categoryChild.add(jsonObject2);
        }
        // 将 category2Child list 整体 赋值到 jsonObject 1中
        jsonObject.put("categoryChild",categoryChild);

        return jsonObject;
    }

    /**
     * 根据一级分类id获取三级分类数据
     * @param category1Id
     * @return
     */
    @Override
    public List<BaseCategory3> findChannel(Long category1Id) {
        // select * from base_category3 where base_category3.category2_id in (101,102,103) and is_top = 1 limit 7;
        // 先根据一级分类Id 找到二级分类集合
        List<BaseCategory2> baseCategory2By1Ids = baseCategory2Mapper.selectList(new LambdaQueryWrapper<BaseCategory2>().eq(BaseCategory2::getCategory1Id, category1Id));
        //将二级分类集合 中的id转成 list 共查询三级信息时 in条件使用
        List<Long> baseCategory2Ids = baseCategory2By1Ids.stream().map(BaseCategory2::getId).collect(Collectors.toList());
        // 查询置顶消息，每页显示7条数据；
        List<BaseCategory3> baseCategory3Infos = baseCategory3Mapper.selectList(new LambdaQueryWrapper<BaseCategory3>().in(BaseCategory3::getCategory2Id, baseCategory2Ids).eq(BaseCategory3::getIsTop, 1).last(" limit 7"));
        return baseCategory3Infos;
    }

}
